/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "包节点.h"

#include "../节点树.h"
#include "../Core/Py数据处理.h"

#include "../插座/C_数值插座.h"
#include "../插座/list/list数值插座.h"
#include "../插座/list/list矢量插座.h"
#include "../插座/list/list元素插座.h"
#include "../插座/list/list键值插座.h"
#include "../插座/list/list物体插座.h"

#include "../插座/socket_utils.h"
//#include "../../创建插座.h"

using namespace std;



static map<string, vector<C_节点树*>>		g_函数实例树;








C_组输入节点::C_组输入节点(PyObject * blNode)
	:C_节点基类(blNode, E_节点类型::e_节点Type_组输入)
{

}

/*void C_组输入节点::f_add插座(C_插座基类 * s, E_插座输出方向 方向) {
	C_节点基类::f_add插座(s, 方向);

	C_插座基类* 容器节点输入插座 = f_创建节点插座(s->m_identifier, s->m_插座类型);
	if(方向 == E_插座输出方向::e_插座Type_输出){
		m_容器节点->f_add插座(容器节点输入插座, E_插座输出方向::e_插座Type_输入);
	} else {
		m_容器节点->f_add插座(容器节点输入插座, E_插座输出方向::e_插座Type_输出);
	}
}

void C_组输入节点::f_del插座(const string name, E_插座输出方向 方向) {
	C_节点基类::f_del插座(name, 方向);

	if (方向 == E_插座输出方向::e_插座Type_输出) {
		m_容器节点->f_del插座(name, E_插座输出方向::e_插座Type_输入);
	} else {
		m_容器节点->f_del插座(name, E_插座输出方向::e_插座Type_输出);
	}
}*/

void C_组输入节点::f_update() {

}

C_节点基类* C_组输入节点::f_get上层节点() {
	return m_容器节点;
}






C_组输出节点::C_组输出节点(PyObject * blNode)
	: C_节点基类(blNode, E_节点类型::e_节点Type_组输出)
{

}

/*void C_组输出节点::f_add插座(C_插座基类 * s, E_插座输出方向 方向) {
	C_节点基类::f_add插座(s, 方向);


	C_插座基类* 容器节点输入插座 = f_创建节点插座(s->m_identifier, s->m_插座类型);
	if (方向 == E_插座输出方向::e_插座Type_输出) {
		m_容器节点->f_add插座(容器节点输入插座, E_插座输出方向::e_插座Type_输入);
	}
	else {
		m_容器节点->f_add插座(容器节点输入插座, E_插座输出方向::e_插座Type_输出);
	}
}

void C_组输出节点::f_del插座(const string name, E_插座输出方向 方向) {
	C_节点基类::f_del插座(name, 方向);

	if (方向 == E_插座输出方向::e_插座Type_输出) {
		m_容器节点->f_del插座(name, E_插座输出方向::e_插座Type_输入);
	} else {
		m_容器节点->f_del插座(name, E_插座输出方向::e_插座Type_输出);
	}
}*/

void C_组输出节点::f_update() {
	uint16 outSocketNum = f_get输入插座Num();

	/*for (uint16 i = 0; i < outSocketNum; ++i) {
		auto* in_s = m_NodeGroupOutput->f_get输入插座(i);
		auto* out_s = f_get输出插座(in_s->m_identifier);
		//auto* in_s = m_NodeGroupOutput->f_get输入插座(out_s->m_identifier);

		if (out_s) out_s->f_setData(in_s->f_getData());
	}*/
}

C_节点基类* C_组输出节点::f_get上层节点() {
	return m_容器节点;
}

void C_组输出节点::f_释放数据() {
	for (auto& socket : m_inputs) {
		socket->f_释放数据();
	}
}
















C_迭代器节点::C_迭代器节点(PyObject * blNode)
	:C_节点基类(blNode)
{
	C_插座基类* socket;
	DEF_Vector_模板插座创建_I("表");

	DEF_引用插座创建_O("元素");
	DEF_创建I32插座_O("ID");

	m_迭代ID = 0;
}

void C_迭代器节点::f_bl节点数据传入(PyObject * bl_data) {

}

PyObject * C_迭代器节点::f_get节点bl数据(PyObject * bl_data) {
	return nullptr;
}

void C_迭代器节点::f_update() {
	C_插座基类* socket = f_get输入插座(1);

	if (socket->f_isLink()) {
		socket = (C_插座基类*)socket->f_getData();

		

		uvec4 id = { 0xffffffff,0xffffffff ,0xffffffff ,0xffffffff };
		void* 迭代数据 = socket->f_getData({ uint32(m_迭代ID),0,0,0 });

		if (迭代数据) {
			C_引用数据插座* 元素 = DEF_转换为引用插座(f_get输出插座(1));
			S_引用插座数据映射 data = { m_数据类型, 迭代数据, id, E_数据赋值方式::e_赋值_直接 };
			元素->f_setData(&data);
		}
		else {
			m_迭代次数 = 0;
			return;
		}
		
		f_get输出插座(2)->f_setData(&m_迭代ID);
	}
	
}

void C_迭代器节点::f_迭代() {
	C_插座基类* socket = f_get输入插座(1);

	
	//socket->f_getData();
	if (socket->f_isLink()) {
		socket = (C_插座基类*)socket->f_getData();


		m_数据类型 = socket->m_Type;
		m_迭代次数 = socket->f_get维度().x;

		switch (m_数据类型) {
		case e_插座Type_Bool:
			break;
		case e_插座Type_LineText:
			break;
		case e_插座Type_Float32:
			break;
		case e_插座Type_Float64:
			break;
		case e_插座Type_Int32:
			m_迭代次数 = DEF_取I32插座值Value(socket);
			m_数据类型 = e_插座Type_Int32;
			break;
		case e_插座Type_UInt32:
			m_迭代次数 = DEF_UI32插座Value(socket);
			m_数据类型 = e_插座Type_Int32;
			break;
		case e_插座Type_Int64:
			break;
		case e_插座Type_Vec2:
			break;
		case e_插座Type_Vec3:
			break;
		case e_插座Type_Vec4:
			break;
		case e_插座Type_Vec2i:
			break;
		case e_插座Type_Vec3i:
			break;
		case e_插座Type_Vec4i:
			break;
		case e_插座Type_Matrix2X2:
			break;
		case e_插座Type_Matrix3X3:
			break;
		case e_插座Type_Matrix4X4:
			break;
		case e_插座Type_Object:
			break;
		case e_插座Type_Mesh:
			//m_数据类型 = e_插座Type_Mesh;
			break;
		case e_插座Type_Line:
			break;
		case e_插座Type_Particles:
			break;
		case e_插座Type_Scene:
			break;
		case e_插座Type_集合:
			break;
		case e_插座Type_面顶点索引:
			break;
		case e_插座Type_车轮:
			break;
		case e_插座Type_车辆:
			break;
		case e_插座Type_物理体:
			break;
		case e_插座Type_物理平面:
			break;
		case e_插座Type_Vector模板:
			break;
		case e_插座Type_Array元素:
			break;
		case e_插座Type_引用数据:
			break;
		case e_插座Type_调试信息:
			break;
		case e_插座Type_F32_Array1D:
			m_数据类型 = e_插座Type_Float32;
			break;
		case e_插座Type_F32_Array2D:
			m_数据类型 = e_插座Type_F32_Array1D;
			break;
		case e_插座Type_I32_Array1D:
			m_数据类型 = e_插座Type_Int32;
			break;
		case e_插座Type_I32_Array2D:
			m_数据类型 = e_插座Type_I32_Array1D;
			break;
		case e_插座Type_UI32_Array3D:
			break;
		case e_插座Type_UI32_Array4D:
			break;
		case e_插座Type_I64_Array1D:
			break;
		case e_插座Type_Vec2_Array1D:
			break;
		case e_插座Type_Vec3_Array1D:
			break;
		case e_插座Type_Vec4_Array1D:
			break;
		case e_插座Type_Vec2i_Array1D:
			break;
		case e_插座Type_Vec3i_Array1D:
			break;
		case e_插座Type_Vec4i_Array1D:
			break;
		case e_插座Type_Mat2X2_Array1D:
			break;
		case e_插座Type_Mat3X3_Array1D:
			break;
		case e_插座Type_Mat4X4_Array1D:
			break;
		case e_插座Type_MapiVec3_Uint32_Array1D:
			break;
		case e_插座Type_MapiVec3_Uint32_Array2D:
			break;
		case e_插座Type_Uint64Map_Uint32_Array2D:
			break;
		case e_插座Type_Object_Array1D:
			break;
		case e_插座Type_Mesh_Array1D:
			m_数据类型 = e_插座Type_Mesh;
			break;
		case e_插座Type_VectorLine:
			break;
		case e_插座Type_VectorParticle:
			break;
		case e_插座Type_VectorScene:
			break;
		case e_插座Type_车轮_Array1D:
			break;
		case e_插座Type_车辆_Array1D:
			break;
		case e_插座Type_物理体_Array1D:
			break;
		case e_插座Type_物理平面_Array1D:
			break;
		default:
			break;
		}
		
	} else {
		m_迭代次数 = 0;
	}
	
}













C_节点树* C_包节点::f_get实例树() {

	return m_节点树;
}

C_包节点::C_包节点(PyObject* blNode, E_节点类型 type) :C_节点基类(blNode, type) {
	m_节点树 = 0;
	m_并发 = false;

	m_NodeGroupIuput = 0;
	m_NodeGroupOutput = 0;
	//m_迭代器节 = 0;
}


void C_包节点::f_add插座(C_插座基类* s, E_插座输出方向 方向) {
	C_节点基类::f_add插座(s, 方向);

	C_插座基类* 容器节点输入插座 = f_创建节点插座(s->m_identifier, s->m_Type);
	if (方向 == E_插座输出方向::e_插座Type_输入) {
		m_NodeGroupIuput->f_add插座(容器节点输入插座, E_插座输出方向::e_插座Type_输出);
	} else {
		m_NodeGroupOutput->f_add插座(容器节点输入插座, E_插座输出方向::e_插座Type_输入);
	}
}

void C_包节点::f_del插座(const string name, E_插座输出方向 方向) {
	C_节点基类::f_del插座(name, 方向);

	if (方向 == E_插座输出方向::e_插座Type_输入) {
		m_NodeGroupIuput->f_del插座(name, E_插座输出方向::e_插座Type_输出);
	} else {
		m_NodeGroupOutput->f_del插座(name, E_插座输出方向::e_插座Type_输入);
	}
}

bool C_包节点::f_移动插座(E_插座输出方向 方向, E_方向 上下, int16 step) {
	bool 是否有操作 = C_节点基类::f_移动插座(方向, 上下, step);
	if (是否有操作) {
		if (方向 == E_插座输出方向::e_插座Type_输入) {
			m_NodeGroupIuput->f_移动插座(E_插座输出方向::e_插座Type_输出, 上下, step);
		}
		else {
			m_NodeGroupOutput->f_移动插座(E_插座输出方向::e_插座Type_输入, 上下, step);
		}
	}
	return 是否有操作;
}


void C_包节点::f_bl节点数据传入(PyObject* bl_data) {
	uint32 num = PyList_Size(bl_data);

	if (num) {
		string type = f_Py字符串转string(PyList_GetItem(bl_data, 0));
		if (type == "tree_name") {
			m_节点树 = f_getTree(f_Py字符串转string(PyList_GetItem(bl_data, 1)));

			m_BL节点树 = PyList_GetItem(bl_data, 2);
			Py_IncRef(m_BL节点树);

			PyObject* inNode = PyList_GetItem(bl_data, 3);
			

			if (!m_NodeGroupIuput) {
				m_NodeGroupIuput = new C_组输入节点(inNode);
				//m_NodeGroupIuput->m_容器节点 = this;
				m_节点树->f_添加节点("Group Input", m_NodeGroupIuput);
			}
			else {
				m_NodeGroupIuput->f_set设置绑定的BL节点(inNode);
			}
			
			PyObject* outNode = PyList_GetItem(bl_data, 4);

			if (!m_NodeGroupOutput) {
				m_NodeGroupOutput = new C_组输出节点(outNode);
				//m_NodeGroupOutput->m_容器节点 = this;
				m_节点树->f_添加节点("Group Output", m_NodeGroupOutput);
			}
			else {
				m_NodeGroupOutput->f_set设置绑定的BL节点(inNode);
			}

			
			m_节点树->f_set父节点(this);
		}
		else if (type == "tree_loop") {
			if (m_节点树) {
				m_迭代器节 = dynamic_cast<C_迭代器节点*>(m_节点树->f_getNode(f_Py字符串转string(PyList_GetItem(bl_data, 1))));

				m_BL节点树 = PyList_GetItem(bl_data, 2);
				Py_IncRef(m_BL节点树);

				if (!m_迭代器节) {
					PyObject* 迭代器 = PyList_GetItem(bl_data, 2);
					m_迭代器节 = new C_迭代器节点(迭代器);
				}

				m_节点树->f_添加节点("迭代器", m_迭代器节);
			}

		}

		return;

		
	}

}

PyObject* C_包节点::f_get节点bl数据(PyObject* bl_data) {
	uint32 num = PyList_Size(bl_data);

	if (num) {
		string type = f_Py字符串转string(PyList_GetItem(bl_data, 0));
		if (type == "tree") {
			Py_IncRef(m_BL节点树);
			return m_BL节点树; 
		}
	}

	return Py_BuildValue("");
}



void C_包节点::f_update() {
	//C_节点基类* upNode = m_节点树->f_get父节点();
	//upNode->f_释放数据();
	vector<string> nodesName;
	m_节点树->f_定点Update(nodesName);

	uint32 层数 = m_节点树->m_层更新节点.size();
	for (uint32 i = 0; i < 层数; ++i) {
		m_节点树->f_Update(i);
	}
}

void C_包节点::f_update输入节点() {
	//初始化内部节点数据
	C_节点树* tree = f_get实例树();
	tree->f_reset();

	if (m_NodeGroupIuput) {
		uint16 inSocketNum = m_inputs.size();

		m_NodeGroupIuput->f_set是否要更新(true);

		for (uint16 i = 0; i < inSocketNum; ++i) {
			auto* in_s	= f_get输入插座(m_inputs[i]->m_identifier);
			auto* out_s	= m_NodeGroupIuput->f_get输出插座(i);
			
			if (in_s) out_s->f_setData(in_s->f_getData());
		}
	}
}

void C_包节点::f_update输出节点() {
	if (m_NodeGroupOutput) {
		uint16 outSocketNum = m_NodeGroupOutput->f_get输入插座Num();

		for (uint16 i = 0; i < outSocketNum; ++i) {
			auto* 输出节点输入插座 = m_NodeGroupOutput->f_get输入插座(i);
			auto* 组节点输出插座 = f_get输出插座(输出节点输入插座->m_identifier);
			//auto* in_s = m_NodeGroupOutput->f_get输入插座(out_s->m_identifier);

			if(组节点输出插座) 组节点输出插座->f_setData(输出节点输入插座->f_getData());
		}
	}
}

C_节点基类* C_包节点::f_get上层节点() {
	return m_节点树->f_get父节点();
}


C_节点基类* C_包节点::f_创建实例() {
	auto* 实例Tree = f_get实例树();

	实例Tree->f_拷贝();

	

	return 0;
}

string C_包节点::f_编译() {
	return string();
}



















C_函数节点::C_函数节点(PyObject * blNode)
	:C_包节点(blNode, E_节点类型::e_节点Type_函数)
{
	
}

void C_函数节点::f_update() {
	if (m_节点树) {
		f_update输入节点();

		m_NodeGroupOutput->f_释放数据();
		f_释放插座数据(E_插座输出方向::e_插座Type_输出);

		C_包节点::f_update();
		f_update输出节点();
	}
}













C_循环节点::C_循环节点(PyObject * blNode)
	:C_包节点(blNode, E_节点类型::e_节点Type_循环)
{

}

void C_循环节点::f_update() {
	if (m_节点树) {
		f_update输入节点();

		m_NodeGroupOutput->f_释放数据();
		f_释放插座数据(E_插座输出方向::e_插座Type_输出);

		if (m_NodeGroupIuput) {
			m_迭代器节->f_迭代();

			for (uint32 i = 0; i < m_迭代器节->m_迭代次数; ++i) {
				m_迭代器节->f_set是否要更新(true);
				m_迭代器节->m_迭代ID = i;
				C_包节点::f_update();
				//cout << "m_迭代器节 = " << m_迭代器节 << endl;
				f_update输出节点();
			}
		}

		
	}
	
}


















